home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / vim / src / param.c < prev    next >
C/C++ Source or Header  |  1995-03-09  |  36KB  |  1,293 lines

  1. /* vi:ts=4:sw=4
  2.  *
  3.  * VIM - Vi IMproved        by Bram Moolenaar
  4.  *
  5.  * Read the file "credits.txt" for a list of people who contributed.
  6.  * Read the file "uganda.txt" for copying and usage conditions.
  7.  */
  8.  
  9. /*
  10.  * Code to handle user-settable parameters. This is all pretty much table-
  11.  * driven. To add a new parameter, put it in the params array, and add a
  12.  * variable for it in param.h. If it's a numeric parameter, add any necessary
  13.  * bounds checks to doset().
  14.  */
  15.  
  16. #include "vim.h"
  17. #include "globals.h"
  18. #include "proto.h"
  19. #include "param.h"
  20.  
  21. struct param
  22. {
  23.     char        *fullname;        /* full parameter name */
  24.     char        *shortname;     /* permissible abbreviation */
  25.     short         flags;            /* see below */
  26.     char_u        *var;            /* pointer to variable */
  27. };
  28.  
  29. /*
  30.  * Flags
  31.  * Note: Don't use P_STRING and P_IND at the same time
  32.  */
  33. #define P_BOOL            0x01    /* the parameter is boolean */
  34. #define P_NUM            0x02    /* the parameter is numeric */
  35. #define P_STRING        0x04    /* the parameter is a string */
  36. #define P_CHANGED        0x08    /* the parameter has been changed */
  37. #define P_EXPAND        0x10    /* environment expansion */
  38. #define P_IND            0x20    /* indirect, is in curwin or curbuf */
  39.  
  40. /*
  41.  * The options that are in curwin or curbuf have P_IND set and a var field
  42.  * that contains one of the values below. The values are odd to make it very
  43.  * unlikely that another variable has the same value.
  44.  * Note: P_EXPAND and P_IND can never be used at the same time.
  45.  * Note: P_IND cannot be used for a terminal option.
  46.  */
  47. #define PV_LIST        1
  48. #define PV_NU        3
  49. #define PV_SCROLL    5
  50. #define PV_WRAP        7
  51.  
  52. #define PV_AI        11
  53. #define PV_BIN        13
  54. #define PV_EOL        14
  55. #define PV_ET        15
  56. #define PV_ML        17
  57. #define PV_RO        19
  58. #define PV_SI        21
  59. #define PV_SN        23
  60. #define PV_SW        25
  61. #define PV_TS        27
  62. #define PV_TW        29
  63. #define PV_TX        31
  64. #define PV_WM        33
  65.  
  66. /*
  67.  * The param structure is initialized here.
  68.  * The order of the parameters should be alfabetic
  69.  * The parameters with a NULL variable are 'hidden': a set command for
  70.  * them is ignored and they are not printed.
  71.  */
  72. static struct param params[] =
  73. {
  74.         {"autoindent",    "ai",    P_BOOL|P_IND,        (char_u *)PV_AI},
  75.         {"autoprint",    "ap",    P_BOOL,                (char_u *)NULL},
  76.         {"autowrite",    "aw",    P_BOOL,                (char_u *)&p_aw},
  77.         {"backspace",    "bs",    P_NUM,                (char_u *)&p_bs},
  78.         {"backup",        "bk",    P_BOOL,                (char_u *)&p_bk},
  79. #ifdef UNIX
  80.          {"backupdir",    "bdir",    P_STRING|P_EXPAND,    (char_u *)&p_bdir},
  81. #endif
  82.         {"beautify",    "bf",    P_BOOL,                (char_u *)NULL},
  83.         {"binary",        "bin",    P_BOOL|P_IND,        (char_u *)PV_BIN},
  84. #ifdef MSDOS
  85.         {"bioskey",        "biosk",P_BOOL,                (char_u *)&p_biosk},
  86. #endif
  87.         {"cmdheight",    "ch",    P_NUM,                (char_u *)&p_ch},
  88.         {"columns",        "co",    P_NUM,                (char_u *)&Columns},
  89.         {"compatible",    "cp",    P_BOOL,                (char_u *)&p_cp},
  90. #ifdef DIGRAPHS
  91.         {"digraph",        "dg",    P_BOOL,                (char_u *)&p_dg},
  92. #endif /* DIGRAPHS */
  93.          {"directory",    "dir",    P_STRING|P_EXPAND,    (char_u *)&p_dir},
  94.         {"edcompatible",NULL,    P_BOOL,                (char_u *)&p_ed},
  95.         {"endofline",    "eol",    P_BOOL|P_IND,        (char_u *)PV_EOL},
  96.         {"equalalways",    "ea",      P_BOOL,                (char_u *)&p_ea},
  97.         {"equalprg",    "ep",      P_STRING|P_EXPAND,    (char_u *)&p_ep},
  98.         {"errorbells",    "eb",    P_BOOL,                (char_u *)&p_eb},
  99.         {"errorfile",    "ef",      P_STRING|P_EXPAND,    (char_u *)&p_ef},
  100.         {"errorformat",    "efm",     P_STRING,            (char_u *)&p_efm},
  101.         {"esckeys",        "ek",    P_BOOL,                (char_u *)&p_ek},
  102.         {"expandtab",    "et",    P_BOOL|P_IND,        (char_u *)PV_ET},
  103.         {"exrc",        NULL,    P_BOOL,                (char_u *)&p_exrc},
  104.         {"formatprg",    "fp",      P_STRING|P_EXPAND,    (char_u *)&p_fp},
  105.         {"gdefault",    "gd",    P_BOOL,                (char_u *)&p_gd},
  106.         {"graphic",        "gr",    P_BOOL,                (char_u *)&p_gr},
  107.         {"hardtabs",    "ht",    P_NUM,                (char_u *)NULL},
  108.         {"helpfile",    "hf",      P_STRING|P_EXPAND,    (char_u *)&p_hf},
  109.         {"hidden",        "hid",    P_BOOL,                (char_u *)&p_hid},
  110.         {"highlight",    "hl",    P_STRING,            (char_u *)&p_hl},
  111.         {"history",     "hi",     P_NUM,                (char_u *)&p_hi},
  112.         {"icon",         NULL,    P_BOOL,                (char_u *)&p_icon},
  113.         {"ignorecase",    "ic",    P_BOOL,                (char_u *)&p_ic},
  114.         {"insertmode",    "im",    P_BOOL,                (char_u *)&p_im},
  115.         {"joinspaces",     "js",    P_BOOL,                (char_u *)&p_js},
  116.         {"keywordprg",    "kp",      P_STRING|P_EXPAND,    (char_u *)&p_kp},
  117.         {"laststatus",    "ls",     P_NUM,                (char_u *)&p_ls},
  118.         {"lines",        NULL,     P_NUM,                (char_u *)&Rows},
  119.         {"lisp",        NULL,    P_BOOL,                (char_u *)NULL},
  120.         {"list",        NULL,    P_BOOL|P_IND,        (char_u *)PV_LIST},
  121.         {"magic",        NULL,    P_BOOL,                (char_u *)&p_magic},
  122.         {"makeprg",        "mp",      P_STRING|P_EXPAND,    (char_u *)&p_mp},
  123.         {"maxmem",        "mm",    P_NUM,                (char_u *)&p_mm},
  124.         {"maxmemtot",    "mmt",    P_NUM,                (char_u *)&p_mmt},
  125.         {"mesg",        NULL,    P_BOOL,                (char_u *)NULL},
  126.         {"modeline",    "ml",    P_BOOL|P_IND,        (char_u *)PV_ML},
  127.         {"modelines",    "mls",    P_NUM,                (char_u *)&p_mls},
  128.         {"more",        NULL,    P_BOOL,                (char_u *)&p_more},
  129.         {"nobuf",        "nb",    P_BOOL,                (char_u *)&p_nb},
  130.         {"number",        "nu",    P_BOOL|P_IND,        (char_u *)PV_NU},
  131.         {"open",        NULL,    P_BOOL,                (char_u *)NULL},
  132.         {"optimize",    "opt",    P_BOOL,                (char_u *)NULL},
  133.         {"paragraphs",    "para",    P_STRING,            (char_u *)&p_para},
  134.         {"paste",        NULL,    P_BOOL,                (char_u *)&p_paste},
  135.         {"patchmode",   "pm",   P_STRING,            (char_u *)&p_pm},
  136.         {"path",        "pa",      P_STRING|P_EXPAND,    (char_u *)&p_path},
  137.         {"prompt",        NULL,    P_BOOL,                (char_u *)NULL},
  138.         {"readonly",    "ro",    P_BOOL|P_IND,        (char_u *)PV_RO},
  139.         {"redraw",        NULL,    P_BOOL,                (char_u *)NULL},
  140.         {"remap",        NULL,    P_BOOL,                (char_u *)&p_remap},
  141.         {"report",        NULL,    P_NUM,                (char_u *)&p_report},
  142.         {"revins",        "ri",    P_BOOL,                (char_u *)&p_ri},
  143.         {"ruler",        "ru",    P_BOOL,                (char_u *)&p_ru},
  144.         {"scroll",        NULL,     P_NUM|P_IND,        (char_u *)PV_SCROLL},
  145.         {"scrolljump",    "sj",     P_NUM,                (char_u *)&p_sj},
  146.         {"sections",    "sect",    P_STRING,            (char_u *)&p_sections},
  147.         {"secure",        NULL,    P_BOOL,                (char_u *)&p_secure},
  148.         {"shell",        "sh",    P_STRING|P_EXPAND,    (char_u *)&p_sh},
  149.         {"shellpipe",    "sp",    P_STRING,            (char_u *)&p_sp},
  150.         {"shelltype",    "st",    P_NUM,                (char_u *)&p_st},
  151.         {"shiftround",    "sr",    P_BOOL,                (char_u *)&p_sr},
  152.         {"shiftwidth",    "sw",    P_NUM|P_IND,        (char_u *)PV_SW},
  153. #ifndef MSDOS
  154.         {"shortname",    "sn",    P_BOOL|P_IND,        (char_u *)PV_SN},
  155. #endif
  156.         {"showcmd",        "sc",    P_BOOL,                (char_u *)&p_sc},
  157.         {"showmatch",    "sm",    P_BOOL,                (char_u *)&p_sm},
  158.         {"showmode",    "smd",    P_BOOL,                (char_u *)&p_smd},
  159.         {"sidescroll",    "ss",    P_NUM,                (char_u *)&p_ss},
  160.         {"slowopen",    "slow",    P_BOOL,                (char_u *)NULL},
  161.         {"smartindent", "si",    P_BOOL|P_IND,        (char_u *)PV_SI},
  162.         {"smarttab",    "sta",    P_BOOL,                (char_u *)&p_sta},
  163.         {"sourceany",    NULL,    P_BOOL,                (char_u *)NULL},
  164.         {"splitbelow",    "sb",    P_BOOL,                (char_u *)&p_sb},
  165.         {"suffixes",    "su",    P_STRING,            (char_u *)&p_su},
  166.         {"tabstop",     "ts",    P_NUM|P_IND,        (char_u *)PV_TS},
  167.         {"taglength",    "tl",    P_NUM,                (char_u *)&p_tl},
  168.         {"tagrelative",    "tr",    P_BOOL,                (char_u *)&p_tr},
  169.         {"tags",        NULL,    P_STRING|P_EXPAND,    (char_u *)&p_tags},
  170.         {"term",        NULL,    P_STRING|P_EXPAND,    (char_u *)&term_strings.t_name},
  171.         {"terse",        NULL,    P_BOOL,                (char_u *)&p_terse},
  172.         {"textauto",    "ta",    P_BOOL,                (char_u *)&p_ta},
  173.         {"textmode",    "tx",    P_BOOL|P_IND,        (char_u *)PV_TX},
  174.         {"textwidth",    "tw",    P_NUM|P_IND,        (char_u *)PV_TW},
  175.         {"tildeop",     "to",    P_BOOL,                (char_u *)&p_to},
  176.         {"timeout",     NULL,    P_BOOL,                (char_u *)&p_timeout},
  177.         {"timeoutlen",    "tm",    P_NUM,                (char_u *)&p_tm},
  178.         {"title",         NULL,    P_BOOL,                (char_u *)&p_title},
  179.         {"ttimeout",     NULL,    P_BOOL,                (char_u *)&p_ttimeout},
  180.         {"ttyfast",     "tf",    P_BOOL,                (char_u *)&p_tf},
  181.         {"ttytype",        NULL,    P_STRING,            (char_u *)NULL},
  182.         {"undolevels",    "ul",    P_NUM,                (char_u *)&p_ul},
  183.         {"updatecount",    "uc",    P_NUM,                (char_u *)&p_uc},
  184.         {"updatetime",    "ut",    P_NUM,                (char_u *)&p_ut},
  185.         {"visualbell",    "vb",    P_BOOL,                (char_u *)&p_vb},
  186.         {"w300",        NULL,     P_NUM,                (char_u *)NULL},
  187.         {"w1200",        NULL,     P_NUM,                (char_u *)NULL},
  188.         {"w9600",        NULL,     P_NUM,                (char_u *)NULL},
  189.         {"warn",        NULL,    P_BOOL,                (char_u *)&p_warn},
  190.         {"weirdinvert",    "wi",    P_BOOL,                (char_u *)&p_wi},
  191.         {"whichwrap",    "ww",    P_NUM,                (char_u *)&p_ww},
  192.         {"wildchar",    "wc",     P_NUM,                (char_u *)&p_wc},
  193.         {"window",        NULL,     P_NUM,                (char_u *)NULL},
  194.         {"winheight",    "wh",    P_NUM,                (char_u *)&p_wh},
  195.         {"wrap",        NULL,    P_BOOL|P_IND,        (char_u *)PV_WRAP},
  196.         {"wrapmargin",    "wm",    P_NUM|P_IND,        (char_u *)PV_WM},
  197.         {"wrapscan",    "ws",    P_BOOL,                (char_u *)&p_ws},
  198.         {"writeany",    "wa",    P_BOOL,                (char_u *)&p_wa},
  199.         {"writebackup",    "wb",    P_BOOL,                (char_u *)&p_wb},
  200.         {"yankendofline", "ye",    P_BOOL,                (char_u *)&p_ye},
  201.  
  202. /* terminal output codes */
  203.         {"t_cdl",        NULL,    P_STRING,    (char_u *)&term_strings.t_cdl},
  204.         {"t_ci",        NULL,    P_STRING,    (char_u *)&term_strings.t_ci},
  205.         {"t_cil",        NULL,    P_STRING,    (char_u *)&term_strings.t_cil},
  206.         {"t_cm",        NULL,    P_STRING,    (char_u *)&term_strings.t_cm},
  207.         {"t_cri",        NULL,    P_STRING,    (char_u *)&term_strings.t_cri},
  208.         {"t_cv",        NULL,    P_STRING,    (char_u *)&term_strings.t_cv},
  209.         {"t_cvv",        NULL,    P_STRING,    (char_u *)&term_strings.t_cvv},
  210.         {"t_dl",        NULL,    P_STRING,    (char_u *)&term_strings.t_dl},
  211.         {"t_cs",        NULL,    P_STRING,    (char_u *)&term_strings.t_cs},
  212.         {"t_ed",        NULL,    P_STRING,    (char_u *)&term_strings.t_ed},
  213.         {"t_el",        NULL,    P_STRING,    (char_u *)&term_strings.t_el},
  214.         {"t_il",        NULL,    P_STRING,    (char_u *)&term_strings.t_il},
  215.         {"t_ke",        NULL,    P_STRING,    (char_u *)&term_strings.t_ke},
  216.         {"t_ks",        NULL,    P_STRING,    (char_u *)&term_strings.t_ks},
  217.         {"t_ms",        NULL,    P_STRING,    (char_u *)&term_strings.t_ms},
  218.         {"t_se",        NULL,    P_STRING,    (char_u *)&term_strings.t_se},
  219.         {"t_so",        NULL,    P_STRING,    (char_u *)&term_strings.t_so},
  220.         {"t_ti",        NULL,    P_STRING,    (char_u *)&term_strings.t_ti},
  221.         {"t_tb",        NULL,    P_STRING,    (char_u *)&term_strings.t_tb},
  222.         {"t_tp",        NULL,    P_STRING,    (char_u *)&term_strings.t_tp},
  223.         {"t_sr",        NULL,    P_STRING,    (char_u *)&term_strings.t_sr},
  224.         {"t_te",        NULL,    P_STRING,    (char_u *)&term_strings.t_te},
  225.         {"t_ts",        NULL,    P_STRING,    (char_u *)&term_strings.t_ts},
  226.         {"t_vb",        NULL,    P_STRING,    (char_u *)&term_strings.t_vb},
  227.  
  228. /* terminal key codes */
  229.         {"t_ku",        NULL,    P_STRING,    (char_u *)&term_strings.t_ku},
  230.         {"t_kd",        NULL,    P_STRING,    (char_u *)&term_strings.t_kd},
  231.         {"t_kr",        NULL,    P_STRING,    (char_u *)&term_strings.t_kr},
  232.         {"t_kl",        NULL,    P_STRING,    (char_u *)&term_strings.t_kl},
  233.         {"t_sku",        NULL,    P_STRING,    (char_u *)&term_strings.t_sku},
  234.         {"t_skd",        NULL,    P_STRING,    (char_u *)&term_strings.t_skd},
  235.         {"t_skr",        NULL,    P_STRING,    (char_u *)&term_strings.t_skr},
  236.         {"t_skl",        NULL,    P_STRING,    (char_u *)&term_strings.t_skl},
  237.         {"t_f1",        NULL,    P_STRING,    (char_u *)&term_strings.t_f1},
  238.         {"t_f2",        NULL,    P_STRING,    (char_u *)&term_strings.t_f2},
  239.         {"t_f3",        NULL,    P_STRING,    (char_u *)&term_strings.t_f3},
  240.         {"t_f4",        NULL,    P_STRING,    (char_u *)&term_strings.t_f4},
  241.         {"t_f5",        NULL,    P_STRING,    (char_u *)&term_strings.t_f5},
  242.         {"t_f6",        NULL,    P_STRING,    (char_u *)&term_strings.t_f6},
  243.         {"t_f7",        NULL,    P_STRING,    (char_u *)&term_strings.t_f7},
  244.         {"t_f8",        NULL,    P_STRING,    (char_u *)&term_strings.t_f8},
  245.         {"t_f9",        NULL,    P_STRING,    (char_u *)&term_strings.t_f9},
  246.         {"t_f10",        NULL,    P_STRING,    (char_u *)&term_strings.t_f10},
  247.         {"t_sf1",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf1},
  248.         {"t_sf2",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf2},
  249.         {"t_sf3",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf3},
  250.         {"t_sf4",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf4},
  251.         {"t_sf5",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf5},
  252.         {"t_sf6",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf6},
  253.         {"t_sf7",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf7},
  254.         {"t_sf8",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf8},
  255.         {"t_sf9",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf9},
  256.         {"t_sf10",        NULL,    P_STRING,    (char_u *)&term_strings.t_sf10},
  257.         {"t_help",        NULL,    P_STRING,    (char_u *)&term_strings.t_help},
  258.         {"t_undo",        NULL,    P_STRING,    (char_u *)&term_strings.t_undo},
  259.         {"t_csc",        NULL,    P_STRING,    (char_u *)&term_strings.t_csc},
  260.         {NULL, NULL, 0, NULL}            /* end marker */
  261. };
  262.  
  263. #define PARAM_COUNT (sizeof(params) / sizeof(struct param))
  264.  
  265. static void param_expand __ARGS((int, int));
  266. static int findparam __ARGS((char_u *));
  267. static void    showparams __ARGS((int));
  268. static void showonep __ARGS((struct param *));
  269. static int  istermparam __ARGS((struct param *));
  270. static char_u *get_varp __ARGS((struct param *));
  271.  
  272. /*
  273.  * Initialize the shell parameter and scroll size.
  274.  */
  275.     void
  276. set_init()
  277. {
  278.     char_u    *p;
  279.     int        i;
  280.  
  281.     if ((p = vimgetenv((char_u *)"SHELL")) != NULL
  282. #ifdef MSDOS
  283.             || (p = vimgetenv((char_u *)"COMSPEC")) != NULL
  284. #endif
  285.                                                             )
  286.     {
  287.         p = strsave(p);
  288.         if (p != NULL)        /* we don't want a NULL */
  289.             p_sh = p;
  290.     }
  291.  
  292. #ifdef UNIX
  293.     /*
  294.      * Default for p_sp is "| tee".
  295.      * For known shells it is changed here to include stderr.
  296.      */
  297.     p = gettail(p_sh);
  298.     if (     STRCMP(p, "csh") == 0 ||
  299.              STRCMP(p, "tcsh") == 0 ||
  300.              STRCMP(p, "zsh") == 0)
  301.         p_sp = (char_u *)"|& tee";
  302.     else if (STRCMP(p, "sh") == 0 ||
  303.              STRCMP(p, "ksh") == 0 ||
  304.              STRCMP(p, "bash") == 0)
  305.         p_sp = (char_u *)"2>&1| tee";
  306. #endif
  307.  
  308.     curwin->w_p_scroll = (Rows >> 1);
  309.     comp_col();
  310.  
  311. /*
  312.  * set the options in curwin and curbuf that are non-zero
  313.  */
  314.     curwin->w_p_wrap = TRUE;
  315.     curbuf->b_p_ml = TRUE;
  316.     curbuf->b_p_sw = 8;
  317.     curbuf->b_p_ts = 8;
  318. #ifdef MSDOS
  319.     curbuf->b_p_tx = TRUE;        /* texmode is default for MSDOS */
  320. #endif
  321.  
  322.     /*
  323.      * expand environment variables in some string options
  324.      */
  325.     for (i = 0; params[i].fullname != NULL; i++)
  326.         param_expand(i, FALSE);
  327.     
  328.     /*
  329.      * may adjust p_mmt and p_mm for available memory
  330.      */
  331.     if (p_mmt == 0)
  332.     {
  333.         p_mmt = (mch_avail_mem(FALSE) >> 11);
  334.         if (p_mm > p_mmt)
  335.             p_mm = p_mmt;
  336.     }
  337. }
  338.  
  339. /*
  340.  * parse 'arg' for option settings
  341.  * 'arg' may be IObuff, but only when no errors can be present and parameter
  342.  * does not need to be expanded with param_expand().
  343.  *
  344.  * return FAIL if errors are detected, OK otherwise
  345.  */
  346.     int
  347. doset(arg)
  348.     char_u        *arg;    /* parameter string (may be written to!) */
  349. {
  350.     register int i;
  351.     char_u        *s;
  352.     char_u        *errmsg;
  353.     char_u        *startarg;
  354.     int            prefix;    /* 0: nothing, 1: "no", 2: "inv" in front of name */
  355.     int         nextchar;
  356.     int         len;
  357.     int         flags;                /* flags for current option */
  358.     char_u        *varp;                /* pointer to variable for current option */
  359.     int            errcnt = 0;            /* number of errornous entries */
  360.     long        oldRows = Rows;        /* remember old Rows */
  361.     int            oldpaste = p_paste;    /* remember old paste option */
  362.     long        oldch = p_ch;        /* remember old command line height */
  363.     int            oldea = p_ea;        /* remember old 'equalalways' */
  364.     long        olduc = p_uc;        /* remember old 'updatecount' */
  365.     static int    save_sm = 0;        /* saved options for 'paste' */
  366.     static int    save_ru = 0;
  367.     static int    save_ri = 0;
  368.     int            did_show = FALSE;    /* already showed one value */
  369.     WIN            *wp;
  370.  
  371.     if (*arg == NUL)
  372.     {
  373.         showparams(0);
  374.         return OK;
  375.     }
  376.     if (STRNCMP(arg, "all", (size_t)3) == 0)
  377.     {
  378.         showparams(1);
  379.         return OK;
  380.     }
  381.     if (STRNCMP(arg, "termcap", (size_t)7) == 0)
  382.     {
  383.         showparams(2);
  384.         return OK;
  385.     }
  386.  
  387.     while (*arg)        /* loop to process all parameters */
  388.     {
  389.         errmsg = NULL;
  390.         startarg = arg;        /* remember for error message */
  391.         prefix = 1;
  392.         if (STRNCMP(arg, "no", (size_t)2) == 0)
  393.         {
  394.             prefix = 0;
  395.             arg += 2;
  396.         }
  397.         else if (STRNCMP(arg, "inv", (size_t)3) == 0)
  398.         {
  399.             prefix = 2;
  400.             arg += 3;
  401.         }
  402.             /* find end of name */
  403.         for (len = 0; isalnum(arg[len]) || arg[len] == '_'; ++len)
  404.             ;
  405.         nextchar = arg[len];
  406.         arg[len] = 0;                                /* name ends with 0 */
  407.         i = findparam(arg);
  408.         arg[len] = nextchar;                        /* restore nextchar */
  409.  
  410.         if (i == -1)        /* found a mismatch: skip the rest */
  411.         {
  412.             errmsg = (char_u *)"Unknown option";
  413.             goto skip;
  414.         }
  415.  
  416.         if (!params[i].var)            /* hidden option */
  417.             goto skip;
  418.  
  419.         flags = params[i].flags;
  420.         varp = get_varp(&(params[i]));
  421.  
  422.         /*
  423.          * allow '=' and ':' as MSDOS command.com allows only one
  424.          * '=' character per "set" command line. grrr. (jw)
  425.          */
  426.         if (nextchar == '?' || 
  427.             (prefix == 1 && nextchar != '=' &&
  428.              nextchar != ':' && !(flags & P_BOOL)))
  429.         {                                        /* print value */
  430.             if (did_show)
  431.                 msg_outchar('\n');        /* cursor below last one */
  432.             else
  433.             {
  434.                 gotocmdline(TRUE, NUL);    /* cursor at status line */
  435.                 did_show = TRUE;        /* remember that we did a line */
  436.             }
  437.             showonep(¶ms[i]);
  438.         }
  439.         else
  440.         {
  441.             if (nextchar != NUL && strchr("=: \t", nextchar) == NULL)
  442.             {
  443.                 errmsg = e_invarg;
  444.                 goto skip;
  445.             }
  446.             else if (flags & P_BOOL)                    /* boolean */
  447.             {
  448.                 if (nextchar == '=' || nextchar == ':')
  449.                 {
  450.                     errmsg = e_invarg;
  451.                     goto skip;
  452.                 }
  453.                 /*
  454.                  * in secure mode, setting of the secure option is not allowed
  455.                  */
  456.                 if (secure && (int *)varp == &p_secure)
  457.                 {
  458.                     errmsg = (char_u *)"not allowed here";
  459.                     goto skip;
  460.                 }
  461.                 if (prefix == 2)
  462.                     *(int *)(varp) ^= 1;    /* invert it */
  463.                 else
  464.                     *(int *)(varp) = prefix;
  465.                     /* handle compatible option here */
  466.                 if ((int *)varp == &p_cp && p_cp)
  467.                 {
  468.                     p_bs = 0;        /* normal backspace */
  469.                     p_ww = 0;        /* backspace and space do not wrap */
  470.                     p_bk = 0;        /* no backup file */
  471. #ifdef DIGRAPHS
  472.                     p_dg = 0;        /* no digraphs */
  473. #endif /* DIGRAPHS */
  474.                     p_ek = 0;        /* no ESC keys in insert mode */
  475.                     curbuf->b_p_et = 0;        /* no expansion of tabs */
  476.                     p_gd = 0;        /* /g is not default for :s */
  477.                     p_hi = 0;         /* no history */
  478.                     p_im = 0;        /* do not start in insert mode */
  479.                     p_js = 1;        /* insert 2 spaces after period */
  480.                     curbuf->b_p_ml = 0;        /* no modelines */
  481.                     p_more = 0;        /* no -- more -- for listings */
  482.                     p_ru = 0;        /* no ruler */
  483.                     p_ri = 0;        /* no reverse insert */
  484.                     p_sj = 1;        /* no scrolljump */
  485.                     p_sr = 0;        /* do not round indent to shiftwidth */
  486.                     p_sc = 0;        /* no showcommand */
  487.                     p_smd = 0;        /* no showmode */
  488.                     curbuf->b_p_si = 0;        /* no smartindent */
  489.                     p_sta = 0;        /* no smarttab */
  490.                     p_ta = 0;        /* no automatic textmode detection */
  491.                     curbuf->b_p_tw = 0;        /* no automatic line wrap */
  492.                     p_to = 0;        /* no tilde operator */
  493.                     p_ttimeout = 0;    /* no terminal timeout */
  494.                     p_tr = 0;        /* tag file names not relative */
  495.                     p_ul = 0;        /* no multilevel undo */
  496.                     p_uc = 0;        /* no autoscript file */
  497.                     p_wb = 0;        /* no backup file */
  498.                     if (p_wc == TAB)
  499.                         p_wc = Ctrl('E');    /* normal use for TAB */
  500.                     p_ye = 0;        /* no yank to end of line */
  501.                 }
  502.                 if ((int *)varp == &curbuf->b_p_bin && curbuf->b_p_bin)    /* handle bin */
  503.                 {
  504.                     curbuf->b_p_tw = 0;        /* no automatic line wrap */
  505.                     curbuf->b_p_wm = 0;        /* no automatic line wrap */
  506.                     curbuf->b_p_tx = 0;        /* no text mode */
  507.                     p_ta = 0;                /* no text auto */
  508.                     curbuf->b_p_ml = 0;        /* no modelines */
  509.                     curbuf->b_p_et = 0;        /* no expandtab */
  510.                 }
  511.                 if ((int *)varp == &p_paste)    /* handle paste here */
  512.                 {
  513.                     BUF        *buf;
  514.  
  515.                     if (p_paste && !oldpaste)    /* paste switched on */
  516.                     {
  517.                             /* save and set options for all buffers */
  518.                         for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  519.                         {
  520.                             buf->b_p_tw_save = buf->b_p_tw;
  521.                             buf->b_p_wm_save = buf->b_p_wm;
  522.                             buf->b_p_ai_save = buf->b_p_ai;
  523.                             buf->b_p_si_save = buf->b_p_si;
  524.                             buf->b_p_tw = 0;        /* textwidth is 0 */
  525.                             buf->b_p_wm = 0;        /* wrapmargin is 0 */
  526.                             buf->b_p_ai = 0;        /* no auto-indent */
  527.                             buf->b_p_si = 0;        /* no smart-indent */
  528.                         }
  529.                             /* save and set global options */
  530.                         save_sm = p_sm;
  531.                         save_ru = p_ru;
  532.                         save_ri = p_ri;
  533.                         p_sm = 0;                /* no showmatch */
  534.                         p_ru = 0;                /* no ruler */
  535.                         p_ri = 0;                /* no reverse insert */
  536.                     }
  537.                     else if (!p_paste && oldpaste)    /* paste switched off */
  538.                     {
  539.                             /* restore options for all buffers */
  540.                         for (buf = firstbuf; buf != NULL; buf = buf->b_next)
  541.                         {
  542.                             buf->b_p_tw = buf->b_p_tw_save;
  543.                             buf->b_p_ai = buf->b_p_ai_save;
  544.                             buf->b_p_si = buf->b_p_si_save;
  545.                         }
  546.                             /* restore global options */
  547.                         p_sm = save_sm;
  548.                         p_ru = save_ru;
  549.                         p_ri = save_ri;
  550.                     }
  551.                 }
  552.                 if (!starting && ((int *)varp == &p_title ||
  553.                                         (int *)varp == &p_icon))
  554.                 {
  555.                     if (*(int *)varp)            /* Set window title NOW */
  556.                         maketitle();
  557.                     else                        /* Reset window title NOW */
  558.                         mch_restore_title((int *)varp == &p_title ? 1 : 2);
  559.                 }
  560.             }
  561.             else                                /* numeric or string */
  562.             {
  563.                 if ((nextchar != '=' && nextchar != ':') || prefix != 1)
  564.                 {
  565.                     errmsg = e_invarg;
  566.                     goto skip;
  567.                 }
  568.                 if (flags & P_NUM)                /* numeric */
  569.                 {
  570.                     *(long *)(varp) = atol((char *)arg + len + 1);
  571.  
  572.                     if ((long *)varp == &p_wh)
  573.                     {
  574.                         if (p_wh < 0)
  575.                         {
  576.                             errmsg = e_positive;
  577.                             p_wh = 0;
  578.                         }
  579.                             /* Change window height NOW */
  580.                         if (p_wh && lastwin != firstwin)
  581.                         {
  582.                             win_equal(curwin, FALSE);
  583.                             must_redraw = CLEAR;
  584.                         }
  585.                     }
  586.                     if ((long *)varp == &p_ls)
  587.                         last_status();        /* (re)set last window status line */
  588.                 }
  589.                 else                            /* string */
  590.                 {
  591.                     arg += len + 1;        /* jump to after the '=' */
  592.                     s = alloc((unsigned)(STRLEN(arg) + 1)); /* get a bit too much */
  593.                     if (s == NULL)
  594.                         break;
  595.                     if (flags & P_CHANGED)
  596.                         free(*(char **)(varp));
  597.                     *(char_u **)(varp) = s;
  598.                                 /* copy the string */
  599.                     while (*arg && *arg != ' ')
  600.                     {
  601.                         if (*arg == '\\' && *(arg + 1)) /* skip over escaped chars */
  602.                                 ++arg;
  603.                         *s++ = *arg++;
  604.                     }
  605.                     *s = NUL;
  606.                     param_expand(i, TRUE);    /* expand environment variables and ~ */
  607.                     /*
  608.                      * options that need some action
  609.                      * to perform when changed (jw)
  610.                      */
  611.                     if (varp == (char_u *)&term_strings.t_name)
  612.                         set_term(term_strings.t_name);
  613.                     else if (istermparam(¶ms[i]))
  614.                     {
  615.                         ttest(FALSE);
  616.                         if (varp == (char_u *)&term_strings.t_tp)
  617.                         {
  618.                             outstr(T_TP);
  619.                             updateScreen(CLEAR);
  620.                         }
  621.                     }
  622.                 }
  623.             }
  624.             params[i].flags |= P_CHANGED;
  625.         }
  626.  
  627. skip:
  628.         /*
  629.          * Check the bounds for numeric parameters here
  630.          */
  631.         if (Rows < 2)
  632.         {
  633.             Rows = 2;
  634.             errmsg = (char_u *)"Need at least 2 lines";
  635.         }
  636.         /*
  637.          * If the screenheight has been changed, assume it is the physical
  638.          * screenheight.
  639.          */
  640.         if (oldRows != Rows)
  641.         {
  642.             screen_new_rows();
  643. #ifdef MSDOS
  644.             set_window();        /* active window may have changed */
  645. #endif
  646.         }
  647.  
  648.         if (curbuf->b_p_ts <= 0)
  649.         {
  650.             errmsg = e_positive;
  651.             curbuf->b_p_ts = 8;
  652.         }
  653.         if (p_tm < 0)
  654.         {
  655.             errmsg = e_positive;
  656.             p_tm = 0;
  657.         }
  658.         if (curwin->w_p_scroll <= 0 || curwin->w_p_scroll > curwin->w_height)
  659.         {
  660.             if (curwin->w_p_scroll != 0)
  661.                 errmsg = e_scroll;
  662.             win_comp_scroll(curwin);
  663.         }
  664.         if (p_report < 0)
  665.         {
  666.             errmsg = e_positive;
  667.             p_report = 1;
  668.         }
  669.         if (p_sj < 0 || p_sj >= Rows)
  670.         {
  671.             errmsg = e_scroll;
  672.             p_sj = 1;
  673.         }
  674.         if (p_uc < 0)
  675.         {
  676.             errmsg = e_positive;
  677.             p_uc = 100;
  678.         }
  679.         if (p_ch < 1)
  680.         {
  681.             errmsg = e_positive;
  682.             p_ch = 1;
  683.         }
  684.         if (p_ut < 0)
  685.         {
  686.             errmsg = e_positive;
  687.             p_ut = 2000;
  688.         }
  689.         if (p_ss < 0)
  690.         {
  691.             errmsg = e_positive;
  692.             p_ss = 0;
  693.         }
  694.         if (errmsg)
  695.         {
  696.             STRCPY(IObuff, errmsg);
  697.             STRCAT(IObuff, ": ");
  698.             s = IObuff + STRLEN(IObuff);
  699.             while (*startarg && !isspace(*startarg))
  700.                 *s++ = *startarg++;
  701.             *s = NUL;
  702.             did_show = TRUE;    /* error message counts as show */
  703.             ++no_wait_return;    /* wait_return done below */
  704.             emsg(IObuff);
  705.             --no_wait_return;
  706.             arg = startarg;        /* skip to next argument */
  707.             ++errcnt;            /* count number of errors */
  708.         }
  709.         skiptospace(&arg);                /* skip to next white space */
  710.         skipspace(&arg);                /* skip spaces */
  711.     }
  712.  
  713.     /*
  714.      * when 'updatecount' changes from zero to non-zero, open swap files
  715.      */
  716.     if (p_uc && !olduc)
  717.         ml_open_files();
  718.  
  719.     if (p_ch != oldch)                    /* p_ch changed value */
  720.         command_height();
  721.     comp_col();
  722.  
  723.     /*
  724.      * Update the screen in case we changed something like "tabstop" or
  725.      * "lines" or "list" that will change its appearance.
  726.      * If we messed up the screen by showing more than one line of param
  727.      * values or an error message, call wait_return(), which will also
  728.      * update the screen.
  729.      */
  730.     for (wp = firstwin; wp; wp = wp->w_next)
  731.         wp->w_redr_status = TRUE;        /* mark all status lines dirty */
  732.     if (p_ea && !oldea)
  733.         win_equal(curwin, FALSE);
  734.     if (did_show && msg_check())
  735.     {
  736.         msg_outchar('\n');
  737.         wait_return(TRUE);
  738.     }
  739.     else
  740.         updateScreen(NOT_VALID);
  741.     return (errcnt == 0 ? OK : FAIL);
  742. }
  743.  
  744. /*
  745.  * expand environment variable at the start of some string options
  746.  */
  747.     static void
  748. param_expand(i, dofree)
  749.     int        i;
  750.     int        dofree;
  751. {
  752.     char_u *p;
  753.  
  754.     if ((params[i].flags & P_EXPAND) &&
  755.                 (p = *(char_u **)(params[i].var)) != NULL &&
  756.                 (*p == '$' || *p == '~'))
  757.     {
  758.         expand_env(*(char_u **)(params[i].var), IObuff, IOSIZE);
  759.         p = strsave(IObuff);
  760.         if (p)
  761.         {
  762.             if (dofree)
  763.                 free(*(char_u **)(params[i].var));
  764.             *(char_u **)(params[i].var) = p;
  765.         }
  766.     }
  767. }
  768.  
  769. /*
  770.  * find index for option 'arg'
  771.  * return -1 if not found
  772.  */
  773.     static int
  774. findparam(arg)
  775.     char_u *arg;
  776. {
  777.     int        i;
  778.     char    *s;
  779.  
  780.     for (i = 0; (s = params[i].fullname) != NULL; i++)
  781.     {
  782.         if (STRCMP(arg, s) == 0) /* match full name */
  783.             break;
  784.     }
  785.     if (s == NULL)
  786.     {
  787.         for (i = 0; params[i].fullname != NULL; i++)
  788.         {
  789.             s = params[i].shortname;
  790.             if (s != NULL && STRCMP(arg, s) == 0) /* match short name */
  791.                 break;
  792.             s = NULL;
  793.         }
  794.     }
  795.     if (s == NULL)
  796.         i = -1;
  797.     return i;
  798. }
  799.  
  800. /*
  801.  * mark option 'arg' changed
  802.  */
  803.     void
  804. paramchanged(arg)
  805.     char_u *arg;
  806. {
  807.     int i;
  808.  
  809.     i = findparam(arg);
  810.     if (i >= 0)
  811.         params[i].flags |= P_CHANGED;
  812. }
  813.  
  814. /*
  815.  * if 'all' == 0: show changed parameters
  816.  * if 'all' == 1: show all normal parameters
  817.  * if 'all' == 2: show all terminal parameters
  818.  */
  819.     static void
  820. showparams(all)
  821.     int            all;
  822. {
  823.     struct param   *p;
  824.     int                col;
  825.     int                isterm;
  826.     char_u            *varp;
  827.     struct param    *(items[PARAM_COUNT]);
  828.     int                item_count;
  829.     int                run;
  830.     int                row, rows;
  831.     int                cols;
  832.     int                i;
  833.     int                len;
  834.  
  835. #define INC    19
  836.  
  837.     gotocmdline(TRUE, NUL);
  838.     msg_outstr((char_u *)"--- Parameters ---\n");
  839.  
  840.     /*
  841.      * do the loop two times:
  842.      * 1. display the short items (non-strings and short strings)
  843.      * 2. display the long items (strings)
  844.      */
  845.     for (run = 1; run <= 2 && !got_int; ++run)
  846.     {
  847.         /*
  848.          * collect the items in items[]
  849.          */
  850.         item_count = 0;
  851.         for (p = ¶ms[0]; p->fullname != NULL && !got_int; p++)
  852.         {
  853.             isterm = istermparam(p);
  854.             varp = get_varp(p);
  855.             if (varp && (
  856.                 (all == 2 && isterm) ||
  857.                 (all == 1 && !isterm) ||
  858.                 (all == 0 && (p->flags & P_CHANGED))))
  859.             {
  860.                 if ((p->flags & P_STRING) && *(char_u **)(varp) != NULL)
  861.                     len = STRLEN(p->fullname) + strsize(*(char_u **)(varp));
  862.                 else
  863.                     len = 1;        /* a non-string is assumed to fit always */
  864.                 if ((len <= INC - 4 && run == 1) || (len > INC - 4 && run == 2))
  865.                     items[item_count++] = p;
  866.             }
  867.             breakcheck();
  868.         }
  869.         /*
  870.          * display the items
  871.          */
  872.         if (run == 1)
  873.         {
  874.             cols = Columns / INC;
  875.             if (cols == 0)
  876.                 cols = 1;
  877.             rows = (item_count + cols - 1) / cols;
  878.         }
  879.         else    /* run == 2 */
  880.             rows = item_count;
  881.         for (row = 0; row < rows && !got_int; ++row)
  882.         {
  883.             col = 0;
  884.             for (i = row; i < item_count; i += rows)
  885.             {
  886.                 msg_pos(-1, col);                    /* make columns */
  887.                 showonep(items[i]);
  888.                 col += INC;
  889.             }
  890.             msg_outchar('\n');                /* scroll screen one line up */
  891.             flushbuf();
  892.             breakcheck();
  893.         }
  894.     }
  895.  
  896.     wait_return(FALSE);
  897. }
  898.  
  899. /*
  900.  * showonep: show the value of one option
  901.  * must not be called with a hidden option!
  902.  */
  903.     static void
  904. showonep(p)
  905.         struct param *p;
  906. {
  907.     char_u            buf[64];
  908.     char_u            *varp;
  909.  
  910.     varp = get_varp(p);
  911.  
  912.     if ((p->flags & P_BOOL) && !*(int *)(varp))
  913.         msg_outstr((char_u *)"no");
  914.     else
  915.         msg_outstr((char_u *)"  ");
  916.     msg_outstr((char_u *)p->fullname);
  917.     if (!(p->flags & P_BOOL))
  918.     {
  919.         msg_outchar('=');
  920.         if (p->flags & P_NUM)
  921.         {
  922.             sprintf((char *)buf, "%ld", *(long *)(varp));
  923.             msg_outstr(buf);
  924.         }
  925.         else if (*(char_u **)(varp) != NULL)
  926.         {
  927.             if (p->flags & P_EXPAND)
  928.             {
  929.                 home_replace(*(char_u **)(varp), NameBuff, MAXPATHL);
  930.                 msg_outtrans(NameBuff, -1);
  931.             }
  932.             else
  933.                 msg_outtrans(*(char_u **)(varp), -1);
  934.         }
  935.     }
  936. }
  937.  
  938. /*
  939.  * Write modified parameters as set command to a file.
  940.  * Return FAIL on error, OK otherwise.
  941.  */
  942.     int
  943. makeset(fd)
  944.     FILE *fd;
  945. {
  946.     struct param    *p;
  947.     char_u            *s;
  948.     int                e;
  949.     char_u            *varp;
  950.  
  951.     for (p = ¶ms[0]; p->fullname != NULL; p++)
  952.         if ((p->flags & P_CHANGED) && p->var)
  953.         {
  954.             varp = get_varp(p);
  955.             if (p->flags & P_BOOL)
  956.                 fprintf(fd, "set %s%s", *(int *)(varp) ? "" : "no", p->fullname);
  957.             else if (p->flags & P_NUM)
  958.                 fprintf(fd, "set %s=%ld", p->fullname, *(long *)(varp));
  959.             else
  960.             {
  961.                 fprintf(fd, "set %s=", p->fullname);
  962.                 s = *(char_u **)(varp);
  963.                     /* some characters hav to be escaped with CTRL-V or backslash */
  964.                 if (s != NULL && putescstr(fd, s, TRUE) == FAIL)
  965.                     return FAIL;
  966.             }
  967. #ifdef MSDOS
  968.             putc('\r', fd);
  969. #endif
  970.                 /*
  971.                  * Only check error for this putc, should catch at least
  972.                  * the "disk full" situation.
  973.                  */
  974.             e = putc('\n', fd);
  975.             if (e < 0)
  976.                 return FAIL;
  977.         }
  978.     return OK;
  979. }
  980.  
  981. /*
  982.  * Clear all the terminal parameters.
  983.  * If the parameter has been changed, free the allocated memory.
  984.  * Reset the "changed" flag, so the new value will not be freed.
  985.  */
  986.     void
  987. clear_termparam()
  988. {
  989.     struct param   *p;
  990.  
  991.     for (p = ¶ms[0]; p->fullname != NULL; p++)
  992.         if (istermparam(p))            /* terminal parameters must never be hidden */
  993.         {
  994.             if (p->flags & P_CHANGED)
  995.                 free(*(char_u **)(p->var));
  996.             *(char_u **)(p->var) = NULL;
  997.             p->flags &= ~P_CHANGED;
  998.         }
  999. }
  1000.  
  1001. /*
  1002.  * return TRUE if 'p' starts with 't_'
  1003.  */
  1004.     static int
  1005. istermparam(p)
  1006.     struct param *p;
  1007. {
  1008.     return (p->fullname[0] == 't' && p->fullname[1] == '_');
  1009. }
  1010.  
  1011. /*
  1012.  * Compute columns for ruler and shown command. 'sc_col' is also used to
  1013.  * decide what the maximum length of a message on the status line can be.
  1014.  * If there is a status line for the last window, 'sc_col' is independent
  1015.  * of 'ru_col'.
  1016.  */
  1017.  
  1018. #define COL_SHOWCMD 10        /* columns needed by shown command */
  1019. #define COL_RULER 17        /* columns needed by ruler */
  1020.  
  1021.     void
  1022. comp_col()
  1023. {
  1024.     int last_status = (p_ls == 2 || (p_ls == 1 && firstwin != lastwin));
  1025.  
  1026.     sc_col = 0;
  1027.     ru_col = 0;
  1028.     if (p_ru)
  1029.     {
  1030.         ru_col = COL_RULER + 1;
  1031.                             /* no last status line, adjust sc_col */
  1032.         if (!last_status)
  1033.             sc_col = ru_col;
  1034.     }
  1035.     if (p_sc)
  1036.     {
  1037.         sc_col += COL_SHOWCMD;
  1038.         if (!p_ru || last_status)        /* no need for separating space */
  1039.             ++sc_col;
  1040.     }
  1041.     sc_col = Columns - sc_col;
  1042.     ru_col = Columns - ru_col;
  1043.     if (sc_col <= 0)            /* screen too narrow, will become a mess */
  1044.         sc_col = 1;
  1045.     if (ru_col <= 0)
  1046.         ru_col = 1;
  1047. }
  1048.  
  1049.     static char_u *
  1050. get_varp(p)
  1051.     struct param    *p;
  1052. {
  1053.     if (!(p->flags & P_IND))
  1054.         return p->var;
  1055.  
  1056.     switch ((long)(p->var))
  1057.     {
  1058.         case PV_LIST:    return (char_u *)&(curwin->w_p_list);
  1059.         case PV_NU:        return (char_u *)&(curwin->w_p_nu);
  1060.         case PV_SCROLL:    return (char_u *)&(curwin->w_p_scroll);
  1061.         case PV_WRAP:    return (char_u *)&(curwin->w_p_wrap);
  1062.  
  1063.         case PV_AI:        return (char_u *)&(curbuf->b_p_ai);
  1064.         case PV_BIN:    return (char_u *)&(curbuf->b_p_bin);
  1065.         case PV_EOL:    return (char_u *)&(curbuf->b_p_eol);
  1066.         case PV_ET:        return (char_u *)&(curbuf->b_p_et);
  1067.         case PV_ML:        return (char_u *)&(curbuf->b_p_ml);
  1068.         case PV_RO:        return (char_u *)&(curbuf->b_p_ro);
  1069.         case PV_SI:        return (char_u *)&(curbuf->b_p_si);
  1070.         case PV_SN:        return (char_u *)&(curbuf->b_p_sn);
  1071.         case PV_SW:        return (char_u *)&(curbuf->b_p_sw);
  1072.         case PV_TS:        return (char_u *)&(curbuf->b_p_ts);
  1073.         case PV_TW:        return (char_u *)&(curbuf->b_p_tw);
  1074.         case PV_TX:        return (char_u *)&(curbuf->b_p_tx);
  1075.         case PV_WM:        return (char_u *)&(curbuf->b_p_wm);
  1076.         default:        EMSG("get_varp ERROR");
  1077.     }
  1078.     /* always return a valid pointer to avoid a crash! */
  1079.     return (char_u *)&(curbuf->b_p_wm);
  1080. }
  1081.  
  1082. /*
  1083.  * Copy options from one window to another.
  1084.  * Used when creating a new window.
  1085.  */
  1086.     void
  1087. win_copy_options(wp_from, wp_to)
  1088.     WIN        *wp_from;
  1089.     WIN        *wp_to;
  1090. {
  1091.     wp_to->w_p_list = wp_from->w_p_list;
  1092.     wp_to->w_p_nu = wp_from->w_p_nu;
  1093.     wp_to->w_p_scroll = wp_from->w_p_scroll;
  1094.     wp_to->w_p_wrap = wp_from->w_p_wrap;
  1095. }
  1096.  
  1097. /*
  1098.  * Copy options from one buffer to another.
  1099.  * Used when creating a new buffer.
  1100.  */
  1101.     void
  1102. buf_copy_options(bp_from, bp_to)
  1103.     BUF        *bp_from;
  1104.     BUF        *bp_to;
  1105. {
  1106.     bp_to->b_p_ai = bp_from->b_p_ai;
  1107.     bp_to->b_p_si = bp_from->b_p_si;
  1108.     bp_to->b_p_ro = bp_from->b_p_ro;
  1109.     bp_to->b_p_sw = bp_from->b_p_sw;
  1110.     bp_to->b_p_ts = bp_from->b_p_ts;
  1111.     bp_to->b_p_tw = bp_from->b_p_tw;
  1112.     bp_to->b_p_wm = bp_from->b_p_wm;
  1113.     bp_to->b_p_bin = bp_from->b_p_bin;
  1114.     bp_to->b_p_et = bp_from->b_p_et;
  1115.     bp_to->b_p_ml = bp_from->b_p_ml;
  1116.     bp_to->b_p_sn = bp_from->b_p_sn;
  1117.     bp_to->b_p_tx = bp_from->b_p_tx;
  1118. }
  1119.  
  1120. #ifdef WEBB_COMPLETE
  1121.     void
  1122. set_context_in_set_cmd(arg)
  1123.     char_u *arg;
  1124. {
  1125.     int         nextchar;
  1126.     int         flags;
  1127.     int            i;
  1128.     char_u        *p;
  1129.     char_u        *after_blank = NULL;
  1130.  
  1131.     expand_context = EXPAND_SETTINGS;
  1132.     if (*arg == NUL)
  1133.     {
  1134.         expand_pattern = arg;
  1135.         return;
  1136.     }
  1137.     p = arg + STRLEN(arg) - 1;
  1138.     if (*p == ' ' && *(p - 1) != '\\')
  1139.     {
  1140.         expand_pattern = p + 1;
  1141.         return;
  1142.     }
  1143.     while (p != arg && (*p != ' ' || *(p - 1) == '\\'))
  1144.     {
  1145.         if (*p == ' ' && after_blank == NULL)
  1146.             after_blank = p + 1;
  1147.         p--;
  1148.     }
  1149.     if (p != arg)
  1150.         p++;
  1151.     if (STRNCMP(p, "no", (size_t) 2) == 0)
  1152.     {
  1153.         expand_context = EXPAND_BOOL_SETTINGS;
  1154.         p += 2;
  1155.     }
  1156.     if (STRNCMP(p, "inv", (size_t) 3) == 0)
  1157.     {
  1158.         expand_context = EXPAND_BOOL_SETTINGS;
  1159.         p += 3;
  1160.     }
  1161.     expand_pattern = arg = p;
  1162.     while (isalnum(*p) || *p == '_' || *p == '*')    /* Allow * as wildcard */
  1163.         p++;
  1164.     if (*p == NUL)
  1165.         return;
  1166.     nextchar = *p;
  1167.     *p = NUL;
  1168.     i = findparam(arg);
  1169.     *p = nextchar;
  1170.     if (i == -1 || params[i].var == NULL)
  1171.     {
  1172.         expand_context = EXPAND_NOTHING;
  1173.         return;
  1174.     }
  1175.     flags = params[i].flags;
  1176.     if (flags & P_BOOL)
  1177.     {
  1178.         expand_context = EXPAND_NOTHING;
  1179.         return;
  1180.     }
  1181.     if ((nextchar != '=' && nextchar != ':')
  1182.       || expand_context == EXPAND_BOOL_SETTINGS)
  1183.     {
  1184.         expand_context = EXPAND_UNSUCCESSFUL;
  1185.         return;
  1186.     }
  1187.     expand_context = EXPAND_NOTHING;
  1188.     if (flags & P_NUM)
  1189.         return;
  1190.     if (after_blank != NULL)
  1191.         expand_pattern = after_blank;
  1192.     else
  1193.         expand_pattern = p + 1;
  1194.     if (flags & P_EXPAND)
  1195.     {
  1196.         p = params[i].var;
  1197.         if (
  1198. #ifdef UNIX
  1199.             p == (char_u *)&p_bdir ||
  1200. #endif
  1201.             p == (char_u *)&p_dir || p == (char_u *)&p_path)
  1202.             expand_context = EXPAND_DIRECTORIES;
  1203.         else
  1204.             expand_context = EXPAND_FILES;
  1205.     }
  1206.     return;
  1207. }
  1208.  
  1209.     int
  1210. ExpandSettings(prog, num_file, file)
  1211.     regexp *prog;
  1212.     int *num_file;
  1213.     char_u ***file;
  1214. {
  1215.     int num_normal = 0;        /* Number of matching non-term-code settings */
  1216.     int num_term = 0;        /* Number of matching terminal code settings */
  1217.     int i;
  1218.     int match;
  1219.     int count;
  1220.     char_u *str;
  1221.  
  1222.     if (expand_context != EXPAND_BOOL_SETTINGS)
  1223.     {
  1224.         if (regexec(prog, (char_u *)"all", TRUE))
  1225.             num_normal++;
  1226.         if (regexec(prog, (char_u *)"termcap", TRUE))
  1227.             num_normal++;
  1228.     }
  1229.     for (i = 0; (str = (char_u *)params[i].fullname) != NULL; i++)
  1230.     {
  1231.         if (params[i].var == NULL)
  1232.             continue;
  1233.         if (expand_context == EXPAND_BOOL_SETTINGS
  1234.           && !(params[i].flags & P_BOOL))
  1235.             continue;
  1236.         if (istermparam(¶ms[i]) && num_normal > 0)
  1237.             continue;
  1238.         match = FALSE;
  1239.         if (regexec(prog, str, TRUE))
  1240.             match = TRUE;
  1241.         else if (params[i].shortname != NULL
  1242.           && regexec(prog, (char_u *)params[i].shortname, TRUE))
  1243.             match = TRUE;
  1244.         if (match)
  1245.         {
  1246.             if (istermparam(¶ms[i]))
  1247.                 num_term++;
  1248.             else
  1249.                 num_normal++;
  1250.         }
  1251.     }
  1252.     if (num_normal > 0)
  1253.         *num_file = num_normal;
  1254.     else if (num_term > 0)
  1255.         *num_file = num_term;
  1256.     else
  1257.         return OK;
  1258.     *file = (char_u **) alloc((unsigned)(*num_file * sizeof(char_u *)));
  1259.     if (*file == NULL)
  1260.     {
  1261.         *file = (char_u **)"";
  1262.         return FAIL;
  1263.     }
  1264.     count = 0;
  1265.     if (expand_context != EXPAND_BOOL_SETTINGS)
  1266.     {
  1267.         if (regexec(prog, (char_u *)"all", TRUE))
  1268.             (*file)[count++] = strsave((char_u *)"all");
  1269.         if (regexec(prog, (char_u *)"termcap", TRUE))
  1270.             (*file)[count++] = strsave((char_u *)"termcap");
  1271.     }
  1272.     for (i = 0; (str = (char_u *)params[i].fullname) != NULL; i++)
  1273.     {
  1274.         if (params[i].var == NULL)
  1275.             continue;
  1276.         if (expand_context == EXPAND_BOOL_SETTINGS
  1277.           && !(params[i].flags & P_BOOL))
  1278.             continue;
  1279.         if (istermparam(¶ms[i]) && num_normal > 0)
  1280.             continue;
  1281.         match = FALSE;
  1282.         if (regexec(prog, str, TRUE))
  1283.             match = TRUE;
  1284.         else if (params[i].shortname != NULL
  1285.           && regexec(prog, (char_u *)params[i].shortname, TRUE))
  1286.             match = TRUE;
  1287.         if (match)
  1288.             (*file)[count++] = strsave(str);
  1289.     }
  1290.     return OK;
  1291. }
  1292. #endif /* WEBB_COMPLETE */
  1293.